home *** CD-ROM | disk | FTP | other *** search
/ 130 MIDI Tool Box / 130 MIDI Tool Box.iso / qb4midi / qbm-dem1.bas next >
BASIC Source File  |  1990-11-27  |  28KB  |  526 lines

  1.      '-------------------------------------------------------------------
  2.      '
  3.      '                     Q U I C K  B A S I C
  4.      '    
  5.      '                   ███ ███ █████ ████  █████
  6.      '                   █ █ █ █   █   █   █   █
  7.      '                   █  █  █   █   █   █   █
  8.      '                   █  █  █ █████ ████  █████
  9.      '
  10.      '             QBMIDI(TM) Library and Sample Programs
  11.      '
  12.      '                    Q B M - D E M 1 . B A S
  13.      '
  14.      '              T U T O T I A L   A N D   D E M O
  15.      '
  16.      '          S H A R E W A R E    V E R S I O N    1 . 0
  17.      '
  18.      '                         Developed by:
  19.      '                 AskUs! Technology Specialists
  20.      '                          PO Box 737
  21.      '                    Bountiful, UT 84011-0737
  22.      '
  23.      '    QBMIDI allows you to easily access a Roland Midi Processing
  24.      '    Unit (MPU401) or compatible MIDI controller from QuickBASIC
  25.      '    version 4.X. QBMIDI uses the files QBMIDI.QLB or QBMIDI.LIB
  26.      '    which contain several simple to use call routines that enable
  27.      '    you access to your MPU401 controller ... and your synthesizers!
  28.      '
  29.      '    If you're just learning QuickBASIC we'll show you how to
  30.      '    start QuickBASIC with these MIDI routines available in real
  31.      '    time, so you can edit and hear your programs work while
  32.      '    in the QuickBASIC environment.  We've also tried to show you
  33.      '    a better understanding of using CALLS to subs, just in case you
  34.      '    have been reluctant to try them.
  35.      '
  36.      '    For sake of readability and understanding for new programmers,
  37.      '    we've tried to write the examples in a simple to understand way
  38.      '    rather than using boolean and subs that would speed things up at
  39.      '    the expense of understandability.  We also use FOR NEXT loops for
  40.      '    timing delays and yes we know they're not accurate at all speeds
  41.      '    and suggest you use time delay routines suitable for your system.
  42.      '    You experienced folk will see many obvious places for program
  43.      '    improvement and by all means .... improve!  But, for this first
  44.      '    lesson, we've written at a greatly simplified level.
  45.      '
  46.      '
  47.      '        QBMIDI is a Trademark of AskUs! Technology Specialists
  48.      '               (c) 1990 AskUs.  All rights reserved.
  49.      '
  50.      '---------------------------------------------------------------------
  51.  
  52.  
  53.      '---------------------------------------------------------------------
  54.      '
  55.      ' Writing A Program That Uses QBMIDI
  56.      '
  57.      ' Since all QBMIDI routines deal in integer numbers, usually from 0 to
  58.      ' 255 we use the DEFINT A-Z command to make using integer variables
  59.      ' easier.  Using integer yields greater execution speed and saves memory
  60.      ' space.  Also, if you compile your programs to .EXE and you avoid the
  61.      ' floating point library (by not using floating point numbers or
  62.      ' functions , your program size should be much smaller by up to 20K.
  63.      '---------------------------------------------------------------------
  64.  
  65.      DEFINT A-Z                              'Always use integers unless specified for speed and space savings
  66.  
  67.      '---------------------------------------------------------------------
  68.      ' Display Headings
  69.      '---------------------------------------------------------------------
  70.  
  71.      SCREEN 0                                'Select normal text screen 0
  72.      CLS                                     'Clear screen
  73.      COLOR 15                                'Use Bright white
  74.      PRINT "QuickBASIC MIDI DEMO          ";
  75.      PRINT "Shareware Version 1.0         ";
  76.      PRINT "(c) 1990 AskUs!"
  77.      COLOR 7                                 'Use Normal white
  78.      PRINT STRING$(80, "─")                  'Print line across top of screen
  79.      VIEW PRINT 4 TO 25                      'Set viewport so messages can scroll under while leaving heading intact
  80.  
  81.      '------------------------------------------------------------------------
  82.      ' You access the QBMIDI routines by calling them as we would call a SUB
  83.      ' procedure or other add-in library routines.  In the next executable
  84.      ' line we call the SeeIfMPUExists routine to do just that .. see if a
  85.      ' MIDI controller is present. If one is found then the variable called
  86.      ' Found will be set to the value -1, otherwise the Found variable will
  87.      ' come back as Zero to indicate a controller was not present.
  88.      '
  89.      ' Now let's call the routine and handle it according to what's found.
  90.      ' Obviously, if a controller is not found, you'd probably hang your CPU
  91.      ' if you tried to continue, so we exit with an error message.
  92.      '------------------------------------------------------------------------
  93.  
  94.      CALL SeeIfMPUExists(Found)              'Check for Midi Processing Unit, Sets Found to -1 if a MPU is found
  95.      IF Found THEN                           'If found then display found message
  96.           PRINT "MPU Found"
  97.      ELSE                                    'Otherwise, if not found end program
  98.           PRINT "MPU Not Found"
  99.           END
  100.      END IF
  101.  
  102.      '------------------------------------------------------------------------
  103.      ' The next routine, ResetMPU, lets you restore the Midi Processing Unit
  104.      ' to its power up state.  We like to issue a reset before starting our
  105.      ' programs to clear out any changes that may have been made by another
  106.      ' MIDI program - and it is much cleaner than asking you to turn your
  107.      ' computer off to clear the unit.  ResetMPU will NOT turn off notes
  108.      ' you may have left on and typically is used only once at the beginning
  109.      ' of your program.
  110.      '
  111.      ' No variable is returned with this Call, so you omit the parenthesis
  112.      ' and a variable name when calling.
  113.      '------------------------------------------------------------------------
  114.  
  115.      CALL ResetMPU                           'Reset MPU to Power up defaults - just in case another program left if with settings changed
  116.  
  117.      '------------------------------------------------------------------------
  118.      ' Following is some normal text to tell you what's going on ...
  119.      '------------------------------------------------------------------------
  120.  
  121.      CLS
  122.      COLOR 15
  123.      PRINT "WELCOME TO QBMIDI ... AND A QUICK SAMPLE OF ITS USE"
  124.      COLOR 7
  125.      PRINT
  126.      PRINT "When running this program we'll describe functions available to you"
  127.      PRINT "from QBMIDI and refer you to parts of the source code for a better"
  128.      PRINT "explanation of what's happening.  We think the best way to learn is from"
  129.      PRINT "example, so we've included well documented examples within this source."
  130.      PRINT
  131.      PRINT "To continue with this program, you'll need the following:"
  132.      PRINT "   IBM COMPATIBLE COMPUTER (6MHz 286 or better is recommended)"
  133.      PRINT "   MIDI CONTROLLER (Roland MPU401, Voyetra OP-4001, or equivalent)"
  134.      PRINT "         attached to the computer, (appx. $100.00 item)"
  135.      PRINT "   SYNTHESIZER with Midi inputs and outputs (appx. $150.00 and up"
  136.      PRINT "         depending on features and type of technology used)"
  137.      PRINT "   MIDI CABLES connecting the Controller to the Synthesizer ($15.00ea)."
  138.      PRINT "         Be sure MIDI OUT on the controller is connected to IN on the synth"
  139.      PRINT "         and IN on the controller hooks to OUT on the synth."
  140.      PRINT "   AMPLIFIED SPEAKER, most higher end synthesizers use external amps."
  141.      PRINT
  142.      PRINT "If you've got the above then hook it up and turn it on!  If not, please"
  143.      PRINT "check with your local musicians shop about purchase (appx. costs given above)."
  144.      PRINT
  145.      GOSUB PressAnyKeyAndAllowExit                          'Ask for any keypress or Esc to exit
  146.  
  147.      '------------------------------------------------------------------------
  148.      ' Now we'll actually play a few notes to see if your system is working
  149.      '------------------------------------------------------------------------
  150.  
  151.      CLS
  152.      COLOR 15
  153.      PRINT "LET'S PLAY A SCALE TO CHECK IF THINGS ARE WORKING"
  154.      COLOR 7
  155.      PRINT
  156.      PRINT "We'll now play a scale to make sure all is working. To do this we've set"
  157.      PRINT "up a FOR NEXT loop to increment the notes when calling the QBMIDI command "
  158.      PRINT "PlayNote.  Midi will recognizes note values from 1 to 127, but we'll play"
  159.      PRINT "only from 41 to 107 since most synthesizers sound a bit muddy at the bottom"
  160.      PRINT "and top ends."
  161.      PRINT
  162.      PRINT "Make sure all components are on, plugged in correctly. Select a sound from"
  163.      PRINT "your front panel on your synthesizer and then press a key to hear your"
  164.      PRINT "QuickBASIC and QBMIDI play a scale."
  165.      PRINT
  166.      GOSUB PressAnyKeyAndAllowExit                          'Ask for any keypress or Esc to exit
  167.  
  168.      '------------------------------------------------------------------------
  169.      ' In the next loop, we use the CALL PlayNote command to send a Note
  170.      ' value and velocity value to the MIDI instrument attached.  With this
  171.      ' call routine, we set the variables Note and Velocity before calling
  172.      ' PlayNote.
  173.      '
  174.      ' Explanation of variables:
  175.      '
  176.      ' NOTE indicates what pitch or note to play.  Each key on a keyboard has
  177.      ' been assigned a number from 1 to 127, with middle C being 60.  Some
  178.      ' synthesizers won't play extremely low or high notes or they remap them
  179.      ' to lowest possible notes.  This causes you to hear the same notes repeat
  180.      ' when playing a scale from 1 to 127.
  181.      '
  182.      ' VELOCITY indicates the amount of pressure applied when striking the
  183.      ' note from a keyboard.  If you are playing a soft piece of music, the
  184.      ' velocity may range from 40 to 80. If playing loud, you may hit the
  185.      ' keys harder, thereby increasing the velocity of the keypress. You
  186.      ' specify how hard the key is pressed from 1 (softest) to 127 (hardest).
  187.      '
  188.      ' Valid ranges for PlayNote variables are:
  189.      '
  190.      '    Note     = 1 to 127   1 being lowest note possible, 127 the highest
  191.      '    Velocity = 1 to 127   1 being soft touch, 127 being hardest touch
  192.      '
  193.      ' Once a sound has been turned on, it will stay on until you turn it
  194.      ' off.  Turn it off by sending a velocity of Zero (0) to PlayNote
  195.      ' along with the Note you wish to turn off.  In the following example
  196.      ' we turn on a note, wait a while, then turn it off using Velocity of 0.
  197.      '
  198.      ' No variables are changed, so the Note and Velocity variables are left
  199.      ' intact so you can call repeatedly, without resetting the variable.
  200.      '------------------------------------------------------------------------
  201.  
  202.      Note = 38                               'Starting note (hopefully above the muddy notes on some keyboards)
  203.      DO                                      'Begin a loop to play the scale
  204.           Note = Note + 3                    'Increment Note by 3 (Change to 1 and re-run)
  205.  
  206.           LOCATE , 1                         'Put cursor at beginning of line
  207.           PRINT "Not playing note ... ";     'Display message
  208.           COLOR 15                           'Set text to high brightness
  209.           PRINT Note; " ";                   'Display current not being played
  210.           COLOR 7                            'Set text color to normal brightness
  211.           Velocity = 120                     'Strong Key Strike Velocities (Range os 1 - 127)
  212.           CALL PlayNote(Note, Velocity)      'Send the Note out Midi to all Synths attached
  213.  
  214.           FOR tmp = 1 TO 15000: NEXT tmp     'Wait a little while (Modify on you machine as needed)
  215.  
  216.           Velocity = 0                       'Now turn off the note by sending a velocity of Zero along with which note to make zero
  217.           CALL PlayNote(Note, Velocity)      'Send the Note out Midi to all Synths attached
  218.  
  219.      LOOP UNTIL Note > 105
  220.  
  221.      PRINT
  222.      PRINT
  223.      PRINT "You should have heard a scale played in steps of every third note. If not"
  224.      PRINT "check your connections, volume, and sound you've selected then restart."
  225.      PRINT
  226.      GOSUB PressAnyKeyAndAllowExit           'Ask for any keypress or Esc to exit
  227.  
  228.  
  229.      '------------------------------------------------------------------------
  230.      ' Create a chord by calling PlayNote several times, specifying different
  231.      ' notes for each call, then waiting to turn off the note.
  232.      '------------------------------------------------------------------------
  233.  
  234.      CLS
  235.      COLOR 15
  236.      PRINT "CHORDS"
  237.      COLOR 7
  238.      PRINT
  239.      PRINT "Now we'll play a three part chord.  This is done by sending three PlayNote"
  240.      PRINT "commands in succession, and leaving all three turned on until we individually"
  241.      PRINT "turn them back off.  Let's listen to a chord."
  242.      GOSUB PressAnyKeyAndAllowExit           'Ask for any keypress or Esc to exit
  243.  
  244.      '------------------------------------------------------------------------
  245.      ' Three PlayNote Commands Are Issued with Velocities Set to 120 (Quite Hard)
  246.      '------------------------------------------------------------------------
  247.  
  248.      Velocity = 120                          'Strong Key Strike Velocities (Range os 1 - 127)
  249.      Note = 29                               'Note Range is between 1 - 127
  250.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached
  251.  
  252.      Velocity = 120                          'Strong Key Strike Velocities (Range os 1 - 127)
  253.      Note = 41                               'Note Range is between 1 - 127
  254.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached
  255.  
  256.      Velocity = 120                          'Strong Key Strike Velocities (Range os 1 - 127)
  257.      Note = 60                               'Note Range is between 1 - 127
  258.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached to turn the Middle C off
  259.  
  260.      PRINT
  261.      PRINT "You're hearing a three part chord.  Notes 29, 41 and 60 were turned on"
  262.      PRINT "above and currently still on.  Press any key to turn the chord off."
  263.      GOSUB PressAnyKey
  264.  
  265.      '------------------------------------------------------------------------
  266.      ' Now We'll turn off the chord by issuing the Same three PlayNote Commands
  267.      ' except we'll set Velocity to zero.  Since PlayNote variables are not
  268.      ' changed, we can specify Velocity once then for all three CALLS.
  269.      '------------------------------------------------------------------------
  270.  
  271.      Velocity = 0                            'Set velocity to zero to turn off note
  272.  
  273.      Note = 29                               'Note Range is between 1 - 127
  274.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached
  275.  
  276.      Note = 41                               'Note Range is between 1 - 127
  277.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached
  278.  
  279.      Note = 60                               'Note Range is between 1 - 127
  280.      CALL PlayNote(Note, Velocity)           'Send the Note out Midi to all Synths attached to turn the Middle C off
  281.  
  282.      PRINT
  283.      PRINT "Now the chord has been turned off."
  284.      GOSUB PressAnyKeyAndAllowExit           'Ask for any keypress or Esc to exit
  285.  
  286.  
  287.      '------------------------------------------------------------------------
  288.      ' Now we'll show changes in Velocity values
  289.      '------------------------------------------------------------------------
  290.  
  291.      CLS
  292.      COLOR 15
  293.      PRINT "VELOCITY VALUES"
  294.      COLOR 7
  295.      PRINT "Whenever a note is turned on using PlayNote you must specify the note"
  296.      PRINT "to play and a velocity value.  Velocity value indicates how hard the key"
  297.      PRINT "would have been pressed if playing from a keyboard.  1 is softest up to 127"
  298.      PRINT "as hardest hit possible. To shut off a note, we send the velocity as 0."
  299.      PRINT
  300.      PRINT "We'll now play the same chord at a three velocity levels, 20, 70 and 127."
  301.      PRINT
  302.      PRINT "Listen to a Velocity value of 20 (simulated light pressure on keyboard)"
  303.      GOSUB PressAnyKey
  304.  
  305.      '------------------------------------------------------------------------
  306.      ' Set the notes we'll use for this chord and call a GOSUB created to play
  307.      ' the chord (and save some space in this program).
  308.      '------------------------------------------------------------------------
  309.  
  310.      Note1 = 60                              'First note in chord
  311.      Note2 = 41                              'Second Note in chord
  312.      Note3 = 29                              'Third note in chord
  313.  
  314.      '------------------------------------------------------------------------
  315.      ' Now set velocity and GOSUB to play the chord
  316.      '------------------------------------------------------------------------
  317.  
  318.      Velocity = 20                           'Soft Key Strike Velocities (Range os 1 - 127)
  319.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  320.  
  321.      PRINT "It's light pressure and may not be heard unless your volume is up."
  322.      GOSUB PressAnyKey
  323.  
  324.      '------------------------------------------------------------------------
  325.      ' After you've pressed a key, we'll send Zero Velocity to turn off the
  326.      ' chord
  327.      '------------------------------------------------------------------------
  328.  
  329.      Velocity = 0                            'Shut off Notes
  330.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  331.  
  332.      '------------------------------------------------------------------------
  333.      ' Now repeat for Velocity 70
  334.      '------------------------------------------------------------------------
  335.  
  336.      PRINT
  337.      PRINT "Listen to a Velocity value of 70 (simulated medium pressure on keyboard)"
  338.      GOSUB PressAnyKey
  339.  
  340.      Velocity = 70                           'Medium Key Strike Velocities (Range os 1 - 127)
  341.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  342.  
  343.      PRINT "This medium pressure should sound about twice as loud as the previous."
  344.      GOSUB PressAnyKey
  345.  
  346.      Velocity = 0                            'Shut off Notes
  347.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  348.  
  349.      '------------------------------------------------------------------------
  350.      ' Now repeat for Velocity 127
  351.      '------------------------------------------------------------------------
  352.  
  353.      PRINT
  354.      PRINT "Listen to a Velocity value of 127 (simulated hardest pressure on keyboard)"
  355.      GOSUB PressAnyKey
  356.  
  357.      Velocity = 127                          'Loudest Key Strike Velocities (Range os 1 - 127)
  358.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  359.  
  360.      PRINT "Playing the hardest hit pressure (velocity) available."
  361.      GOSUB PressAnyKey
  362.  
  363.      Velocity = 0                            'Shut off Notes
  364.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  365.  
  366.      PRINT
  367.      PRINT "You can also change Velocity within the notes of a chord where each key"
  368.      PRINT "receives a different pressure when pressed. We suggest you try a little"
  369.      PRINT "experimenting with this ... a bit later."
  370.      PRINT
  371.      GOSUB PressAnyKeyAndAllowExit           'Ask for any keypress or Esc to exit
  372.  
  373.  
  374.  
  375.      CLS
  376.      COLOR 15
  377.      PRINT "PLAY SCALE OF CHORDS"
  378.      COLOR 7
  379.      PRINT
  380.      PRINT "We'll combine the parts learned so far (play a scale and play a chord) into"
  381.      PRINT "a scale of Chords. We set up a loop for play the scale but call three PlayNote"
  382.      PRINT "commands at a time to play the chord.  Let's listen."
  383.      GOSUB PressAnyKeyAndAllowExit           'Ask for any keypress or Esc to exit
  384.  
  385.      PRINT
  386.  
  387.      Note = 38                               'Starting note (hopefully above the muddy notes on some keyboards)
  388.      DO                                      'Begin a loop to play the scale
  389.           Note = Note + 3                    'Increment Note by 3 (Change to 1 and re-run)
  390.  
  391.           Velocity = 120                     'Strong Key Strike Velocities (Range os 1 - 127)
  392.           Note1 = Note - 12                  'Subtract 12 for bottom note in chord
  393.           Note2 = Note                       'Mid note stays the same
  394.           Note3 = Note + 19                  'Add 19 to get upper note in chord
  395.  
  396.           LOCATE , 1                         'Put cursor at beginning of line
  397.           PRINT "Now playing notes ... ";    'Display message
  398.           COLOR 15                           'Set text to high brightness
  399.           PRINT Note1; "    ";               'Display current not being played
  400.           PRINT Note2; "    ";               'Display current not being played
  401.           PRINT Note3; "    ";               'Display current not being played
  402.           COLOR 7                            'Set text color to normal brightness
  403.  
  404.           GOSUB PlayThreeNoteChord
  405.  
  406.           FOR tmp = 1 TO 15000: NEXT tmp     'Wait a while
  407.  
  408.           Velocity = 0                       'Now turn off the note by sending a velocity of Zero along with which note to make zero
  409.           GOSUB PlayThreeNoteChord
  410.  
  411.      LOOP UNTIL Note > 105
  412.  
  413.      Velocity = 120                          'Hard pressure
  414.      Note1 = 29                              'First note in chord
  415.      Note2 = 41                              'Second Note in chord
  416.      Note3 = 60                              'Third note in chord
  417.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  418.  
  419.      LOCATE , 1                              'Put cursor at beginning of line
  420.      PRINT "Now playing notes ... ";         'Display message
  421.      COLOR 15                                'Set text to high brightness
  422.      PRINT Note1; "    ";                    'Display current not being played
  423.      PRINT Note2; "    ";                    'Display current not being played
  424.      PRINT Note3; "    ";                    'Display current not being played
  425.      COLOR 7                                 'Set text color to normal brightness
  426.  
  427.      FOR tmp = 1 TO 20000                    'Wait quite a while
  428.           FOR j = 1 TO 10                    'Increase by factor of 10
  429.           NEXT j                             'Next
  430.      NEXT tmp                                'Loop til 20,000
  431.  
  432.      Velocity = 0                            'Shut off Notes
  433.      GOSUB PlayThreeNoteChord                'We'll use a subroutine to save some space
  434.  
  435.      PRINT
  436.      GOSUB PressAnyKey                       'Ask for any keypress or Esc to exit
  437.      
  438.  
  439.      '----------------------------------------------------------------------
  440.      ' A final closing note to display
  441.      '----------------------------------------------------------------------
  442.  
  443.      CLS
  444.      COLOR 15
  445.      PRINT "WHAT NEXT"
  446.      COLOR 7
  447.      PRINT
  448.      PRINT "List out this program and modify it using your imagination.  If you wish to"
  449.      PRINT "go further with MIDI than this program allows, we suggest you consider"
  450.      PRINT "purchase of the QBMIDI MUSICIANS VERSION that provides advanced features"
  451.      PRINT "including independent sound control by midi channel, bulk sound data dumps"
  452.      PRINT "and saves, and much more. See the QBMIDI.DOC file for more info."
  453.      PRINT
  454.      PRINT "We hope you like our beginners intro to MIDI and QBMIDI.  Experiment and"
  455.      PRINT "have fun.  We've found that making music with Computers is far more enjoyable"
  456.      PRINT "than writing other types of programs.  And besides, our world doesn't need"
  457.      PRINT "another amortization, biorythm or ultimate menu shell program."
  458.      PRINT
  459.      PRINT "AskUs! for more information or Tell Us what you'd like by writing us at:"
  460.      PRINT
  461.      PRINT "            AskUs!, PO Box 737, Bountiful, UT 84011-0737"
  462.      PRINT
  463.  
  464.      END
  465.  
  466.  
  467.  
  468. '------------------------------- G O S U B S ------------------------------------
  469.  
  470.  
  471.      '----------------------------------------------------------------------
  472.      ' When playing chords, it's easiest to GOSUB to a routine that plays
  473.      ' or shuts off all three (or more) notes in the cord.  We've played
  474.      ' three notes simultaneously but more can be played in a chord or
  475.      ' at once by adding another CALL PlayNote.  Experiment and have fun!
  476.      '----------------------------------------------------------------------
  477.  
  478. PlayThreeNoteChord:
  479.  
  480.      'Note1, Note2 and Note3 should contain the notes to play
  481.      'Velocity should contain desired play velocity or 0 to shut off the
  482.      'note currently playing.
  483.  
  484.      CALL PlayNote(Note1, Velocity)
  485.      CALL PlayNote(Note2, Velocity)
  486.      CALL PlayNote(Note3, Velocity)
  487.  
  488.      RETURN
  489.  
  490.  
  491.      '----------------------------------------------------------------------
  492.      ' We use the press any key in two forms. One that allows exit to the
  493.      ' system and one that doesn't.  We don't allow an exit while notes are
  494.      ' being played.  Again, it's lengthy for readability purposes only.
  495.      '----------------------------------------------------------------------
  496.  
  497. PressAnyKeyAndAllowExit:
  498.      ExitAllowed = -1                             'Set flag (Variable) showing that exit is acceptable
  499.  
  500. PressAnyKey:                                      'Display message at bottom, wait for key, check for escape and end or erase message and return
  501.      DO                                           'Start simple loop to clear out keyboard buffer, just in case characters were left there
  502.      LOOP UNTIL INKEY$ = ""                       'Loop until no more keys are found
  503.      COLOR 15                                     'Use bright level text
  504.      PRINT "Press any key ";                      'Display message
  505.      IF ExitAllowed THEN                          'If Exit OK then ...
  506.           PRINT "(or Esc to quit)";               'Display extended message to say it's ok to use escape
  507.      END IF                                       'End of If Exit check
  508.      COLOR 7                                      'Go back to Normal level text
  509.      DO                                           'Start loop to wait for keypress
  510.           a$ = INKEY$                             'Look for keypress using inkey
  511.      LOOP UNTIL LEN(a$)                           'Loop until length of A$ is greater than 0, in otherwords loop until a character is in A$, LEN(A$)>1
  512.      IF ExitAllowed = -1 THEN                     'If Exit OK then check if escape was pressed
  513.           IF a$ = CHR$(27) THEN                   'Check for the escape key
  514.                PRINT                              'Space to next line
  515.                PRINT "Program stopped"            'Display what happened
  516.                END                                'End the program
  517.           END IF                                  'End of Check for escape key If condition
  518.      END IF                                       'End of Exit Allowed If condition
  519.      LOCATE , 1                                   'Send cursor back to beginning of line
  520.      PRINT STRING$(42, " ");                      'Erase the Press any key message
  521.      LOCATE , 1                                   'Send cursor back to beginning of line for next line to print
  522.      ExitAllowed = 0                              'Set exit OK flag to false in case it was used this time in
  523.      RETURN                                       'Jump back where Gosub brought us here
  524.  
  525.  
  526.